/***********************************************
 **** 版权声明处 **
 ****  为了方便阅读和维护，请严格遵守相关代码规范，谢谢   ****
 *******************************************/
package bpm.graphic
{
	/*******************************************
	 **** huangjixin,2012-10-16,上午9:19:28 **
	 **** 请一句话表述该类主要作用  **
	 *******************************************/
	
	import bpm.graphic.decorators.DecoratorPlayer;
	import bpm.graphic.events.DiagramEditorEvent;
	import bpm.graphic.events.GraphEvent;
	import bpm.graphic.skins.SkinBase;
	
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.ui.Keyboard;
	
	import mx.collections.ArrayCollection;
	import mx.core.IVisualElement;
	import mx.core.IVisualElementContainer;
	import mx.core.UIComponent;
	import mx.events.DragEvent;
	import mx.events.FlexEvent;
	import mx.managers.DragManager;
	
	import spark.components.Group;
	
	public class Graph extends Group
	{
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// private 类私有静态变量和静态常量声明处。（全部大写，使用下划线进行分割）
		// 例如：private static const EXAMPLE:String = "example";
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// public 类公有静态变量和静态常量声明处。（全部大写，使用下划线进行分割）
		// 例如：public static const EXAMPLE:String = "example";
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		public static const DATA_FORMAT:String = "bpmDragDataFormat";
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// private 私有变量声明处，请以“_”开头定义变量
		// 例如：private var _example:String;
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//		private var _selectedObjects:ArrayCollection;
		
		private var copiedObjects:ArrayCollection;
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// public 公有变量声明处
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// 构造函数，初始化相关工作可以放在里面
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		public function Graph()
		{
			super();
			addDragEventListener();
		}
		//构造函数结束
		
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// getter和setter函数
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		/*public function get selectedObjects():ArrayCollection
		{
			return _selectedObjects;
		}

		public function set selectedObjects(value:ArrayCollection):void
		{
			_selectedObjects = value;
		}*/
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// 相关事件响应函数和逻辑函数存放处
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		/**
		 * 清空选择对象组。 
		 * 
		 */
		/*public function clearSelected():void
		{
			for (var i:int = 0; i < selectedObjects.length; i++) 
			{
				var ele:UIComponent = selectedObjects[i];
				if (ele is Render){
					Render(ele).isSelected = false;
					
					
				}
			}
			
			selectedObjects.removeAll();
		}*///clearSelected结束
		
		/*public function deleteSelected():void
		{
			for (var i:int = 0; i < selectedObjects.length; i++) 
			{
				var ele:UIComponent = selectedObjects[i];
				if(ele.parent){
					ele.dispatchEvent(new DiagramEditorEvent(DiagramEditorEvent.EDITOR_DELETE,ele));
					IVisualElementContainer(ele.parent).removeElement(ele);
				}
			}
			
		}*///deleteSelected结束
		
		/**
		 * 找到鼠标所在最深的Graph,如果 currentTarget非空，那么就找到currentTarget下面的Graph对象。
		 * @return 
		 * 
		 */
		public function getDeeplistGraph(event:Event,currentTarget:Object = null):Graph
		{
			if(!stage){
				return null;
			}
			var array:Array = stage.getObjectsUnderPoint(new Point(stage.mouseX, stage.mouseY));
			var graph:Graph = null;
			for (var j:int = array.length-1; j >=0 ; j--) 
			{
				var object:Object = array[j];
				if(object is Graph){
					graph = object as Graph;
				}
				if(object && object.hasOwnProperty("graph")){
					graph = object["graph"] as Graph;
					
					if(!currentTarget){
						break;
					}else{
						if(object.hasOwnProperty("hostComponent")){
							if(object["hostComponent"] == currentTarget){
								continue;
							}else{
								break;
							}
						}
					}
				}/*else if(object is IVisualElementContainer){ //为了支持皮肤里面可以嵌套Group元素而添加。
					var ivisualEleCon:IVisualElementContainer = object as IVisualElementContainer;
					for (var i:int = 0; i < ivisualEleCon.numElements; i++) 
					{
						var ele:UIComponent = ivisualEleCon[i] as UIComponent;
						if(ele.hasOwnProperty("graph")){
							graph = object["graph"] as Graph;
							break;
						}
					}
					
					if(!currentTarget){
						break;
					}else{
						if(object.hasOwnProperty("hostComponent")){
							if(object["hostComponent"] == currentTarget){
								continue;
							}else{
								break;
							}
						}
					}
				}*/
			}
			
			return graph;
		}//getDeeplistGraph结束
		
		public function getDeeplistRender():Render
		{
			if(!stage){
				return null;
			}
			var array:Array = stage.getObjectsUnderPoint(new Point(stage.mouseX, stage.mouseY));
			var render:Render = null;
			for (var j:int = array.length-1; j >=0 ; j--) 
			{
				var object:Object = array[j];
				if(object is SkinBase){
					if(object["hostComponent"] is Render){
						render = object["hostComponent"] as Render;
						break;
					}
				}else if(object.hasOwnProperty("parent")){
					if(object["parent"] is SkinBase){
						var skinBase:SkinBase = object["parent"] as SkinBase;
						if(skinBase["hostComponent"] is Render){
							render = skinBase["hostComponent"] as Render;
							break;
						}
					}
				}
			}
			
			return render;
		}//getDeeplistGraph结
		
		////////////// 拖拽侦听
		/**
		 * 移除拖拽侦听
		 */
		public function removeDragEventListener():void
		{
			this.removeEventListener(DragEvent.DRAG_ENTER, dragEnterHandler);
			this.removeEventListener(DragEvent.DRAG_DROP, dragDropHandler);
		}
		
		/**
		 * 添加拖拽侦听
		 */
		public function addDragEventListener():void
		{
			this.addEventListener(DragEvent.DRAG_ENTER, dragEnterHandler);
			this.addEventListener(DragEvent.DRAG_DROP, dragDropHandler);
		}
		
		/**
		 * 拖放函数,记录拖拽器位置信息等
		 * @param event
		 * 
		 */
		protected function dragDropHandler(event:DragEvent):void
		{
			var object:Object=event.dragSource.dataForFormat(Graph.DATA_FORMAT);
			var classType:String=object.ClassType;
			var hDistance:Number=object.hDistance;
			var vDistance:Number=object.vDistance;
			
			var dragInitiator:Node=event.dragInitiator as Node;
			var instance:UIComponent=dragInitiator.clone() as UIComponent;
			
			
			var graph:Graph = getDeeplistGraph(event);
			if(graph){
				graph.addElement(instance);
				instance.x = graph.mouseX - hDistance;
				instance.y = graph.mouseY - vDistance;
			}else{
				addElement(instance);
				instance.x=mouseX - hDistance;
				instance.y=mouseY - vDistance;
			}
			
			invalidateProperties();
			
			//该孩子的父亲获得焦点。
			UIComponent(instance.parent).setFocus();
			
			if(instance is Render){
//				this.stage.dispatchEvent(new GraphEvent(GraphEvent.SELECTION_CHANGE,instance));
				stage.dispatchEvent(new DiagramEditorEvent(DiagramEditorEvent.EDITOR_CREATE,instance,true));
//				graph.stage.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN));
			}
		}
		
		/**
		 *  
		 * @param event
		 * 
		 */
		protected function dragEnterHandler(event:DragEvent):void
		{
			if (event.dragSource.hasFormat(Graph.DATA_FORMAT))
			{
				DragManager.acceptDragDrop(UIComponent(event.currentTarget));
			}
		}
		
		/*private var currentTarget:UIComponent;
		private var currentGraph:Object;*/
		/**
		 * 更改选择状态。 
		 * @param event
		 * 
		 */
		/*protected function onRenderMouseDown(event:MouseEvent):void
		{
			//必须先截住事件。
			event.stopPropagation();

			//先把变量给定义好。
			var currentTarget:UIComponent = event.currentTarget as UIComponent;
			var render:Render = null;
			if (currentTarget is Render){
				render= currentTarget as Render;
			}
			
			currentTarget.startDrag();
			
			currentTarget.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
			currentTarget.stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
			currentTarget.addEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);
			currentTarget.stage.addEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);
			
			
			this.currentTarget = currentTarget;
			this.currentGraph = getDeeplistGraph(event,this.currentTarget);
		}*/
		
		/**
		 * 舞台对象移动。 
		 * @param event
		 * 
		 */
		/*protected function onStageMouseMove(event:MouseEvent):void
		{
			var currentTarget:UIComponent = this.currentTarget;
			var graph:Graph = getDeeplistGraph(event,currentTarget);
			
			var arr:ArrayCollection = selectedObjects;
			var ele:Node;
			var point:Point;
			
			if(graph != this.currentGraph){
				if(!graph){
					return;
				}
				
				if(!contain(graph,currentTarget)){
					
					point = new Point(currentTarget.x,currentTarget.y);
					point = currentTarget.parent.localToGlobal(point); //關鍵點；
					point = graph.globalToLocal(point);
					currentTarget.x = point.x;
					currentTarget.y = point.y;
					
					if(currentTarget.parent is Graph){
						this.currentGraph.clearSelected();
					}
					
					graph.clearSelected();
					graph.addElement(currentTarget);
					Render(currentTarget).isSelected = true;
					graph.selectedObjects.addItem(currentTarget);
					
					graph.setFocus();
					this.currentGraph = graph;
				}
			}else{
				if(!contain(graph,currentTarget)){
					
					point = new Point(currentTarget.x,currentTarget.y);
					point = currentTarget.parent.localToGlobal(point); //關鍵點；
					point = graph.globalToLocal(point);
					currentTarget.x = point.x;
					currentTarget.y = point.y;

					if(currentTarget.parent is Graph){
						Graph(currentTarget.parent).clearSelected();
					}
					
					graph.clearSelected();
					Render(currentTarget).isSelected = true;
					graph.selectedObjects.addItem(currentTarget);
					graph.addElement(currentTarget);
					
					graph.setFocus();
					this.currentGraph = graph;	
				}
			}
		}*/
		
		
		/**
		 * 
		 * @param container
		 * @param element
		 * @return 
		 * 
		 */
		public function contain(container:IVisualElementContainer,element:IVisualElement):Boolean
		{
			if(!container || !element){
				return false;
			}
			
			for (var i:int = 0; i < container.numElements; i++) 
			{
				var ele:IVisualElement = container.getElementAt(i);
				if(ele){
					if(ele == element){
						return true;
					}
				}
			}
			return false;
			
		}//contain结束
		
		/**
		 * 
		 * @param event
		 * 
		 */
		/*protected function onStageMouseUp(event:MouseEvent):void
		{
			var currentTarget:UIComponent = this.currentTarget;
			currentTarget.stopDrag();
			currentTarget.removeEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
			currentTarget.stage.removeEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
			currentTarget.removeEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);
			currentTarget.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);
			this.currentTarget = null;
			this.currentGraph = null;
		}*/
		
		/////////////////////////// 克隆函数
		/**
		 * 克隆函数； 
		 * @return 
		 * 
		 */
		public function clone():Graph{
			var cloneGraph:Graph = new Graph();
			cloneChildren(this,cloneGraph);
			return cloneGraph;
		}
		
		/**
		 *	规定该容器的孩子必须是Node子后代； 
		 * 
		 */
		public function cloneChildren(graph:Graph,cloneGraph:Graph):void
		{
			for (var i:int = 0; i < graph.numElements; i++) 
			{
				var ele:Node = graph.getElementAt(i) as Node;
				cloneGraph.addElement(ele.clone());
				
				if (ele.hasOwnProperty("graph")){
					var cloneGra:Graph = ele["graph"] as Graph;
					cloneGraph.addElement(cloneGra);
				}
			}
			
		}//cloneChildren结束
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// override 覆盖函数
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		override public function addElement(element:IVisualElement):IVisualElement{
			super.addElement(element);
//			element.addEventListener(MouseEvent.MOUSE_DOWN,onRenderMouseDown);
			return element;
		}
	}//类结束
}//包结束